/**
 * @Author: dn-jinmin
 * @File:  tlog
 * @Version: 1.0.0
 * @Date: 2024/3/7
 * @Description:
 */

package tlog

import (
	"context"
	"fmt"
)

type Logger interface {
	Errorf(relatedId, format string, a ...any)
	Error(relatedId string, msg interface{}, fields ...Field)
	ErrorfCtx(ctx context.Context, relatedId, format string, a ...any)
	ErrorCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field)
	Info(relatedId string, msg interface{}, fields ...Field)
	Infof(relatedId, format string, a ...any)
	InfoCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field)
	InfofCtx(ctx context.Context, relatedId, format string, a ...any)
	Debug(relatedId string, msg interface{}, fields ...Field)
	Debugf(relatedId, format string, a ...any)
	DebugCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field)
	DebugfCtx(ctx context.Context, relatedId, format string, a ...any)
	Slow(relatedId string, msg interface{}, fields ...Field)
	Slowf(relatedId, format string, a ...any)
	SlowCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field)
	SlowfCtx(ctx context.Context, relatedId, format string, a ...any)
	Stat(relatedId string, msg interface{}, fields ...Field)
	Statf(relatedId, format string, a ...any)
	StatCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field)
	StatfCtx(ctx context.Context, relatedId, format string, a ...any)
	Fatal(relatedId string, msg interface{}, fields ...Field)
	Fatalf(relatedId, format string, a ...any)
	FatalCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field)
	FatalfCtx(ctx context.Context, relatedId, format string, a ...any)
	Severe(relatedId string, msg interface{}, fields ...Field)
	Severef(relatedId, format string, a ...any)
	SevereCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field)
	SeverefCtx(ctx context.Context, relatedId, format string, a ...any)
	Alert(relatedId string, msg interface{}, fields ...Field)
	Alertf(relatedId, format string, a ...any)
	AlertCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field)
	AlertfCtx(ctx context.Context, relatedId, format string, a ...any)
}

type logger struct {
	*log
}

func NewLogger(opts ...Options) *logger {
	if defaultLog != nil && len(opts) == 0 {
		return &logger{log: defaultLog}
	}
	return &logger{log: NewLog(opts...)}
}

// ------- error log --------------

func (l *logger) Errorf(relatedId, format string, a ...any) {
	l.log.Write(context.Background(), ERROR, relatedId, fmt.Sprintf(format, a...))
}

func (l *logger) Error(relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(context.Background(), ERROR, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) ErrorfCtx(ctx context.Context, relatedId, format string, a ...any) {
	l.log.Write(ctx, ERROR, relatedId, fmt.Sprintf(format, a...))
}

func (l *logger) ErrorCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(ctx, ERROR, relatedId, MsgMarshal(msg), fields...)
}

// ------- info log --------------

func (l *logger) Info(relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(context.Background(), INFO, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) Infof(relatedId, format string, a ...any) {
	l.log.Write(context.Background(), INFO, relatedId, fmt.Sprintf(format, a...))
}

func (l *logger) InfoCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(ctx, INFO, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) InfofCtx(ctx context.Context, relatedId, format string, a ...any) {
	l.log.Write(ctx, INFO, relatedId, fmt.Sprintf(format, a...))
}

// ----------- debug log ---------------

func (l *logger) Debug(relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(context.Background(), DEBUG, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) Debugf(relatedId, format string, a ...any) {
	l.log.Write(context.Background(), DEBUG, relatedId, fmt.Sprintf(format, a...))
}

func (l *logger) DebugCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(ctx, DEBUG, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) DebugfCtx(ctx context.Context, relatedId, format string, a ...any) {
	l.log.Write(ctx, DEBUG, relatedId, fmt.Sprintf(format, a...))
}

// ----------- slow log ---------------

func (l *logger) Slow(relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(context.Background(), SLOW, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) Slowf(relatedId, format string, a ...any) {
	l.log.Write(context.Background(), SLOW, relatedId, fmt.Sprintf(format, a...))
}

func (l *logger) SlowCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(ctx, SLOW, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) SlowfCtx(ctx context.Context, relatedId, format string, a ...any) {
	l.log.Write(ctx, SLOW, relatedId, fmt.Sprintf(format, a...))
}

// ----------- Stat log ---------------

func (l *logger) Stat(relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(context.Background(), STAT, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) Statf(relatedId, format string, a ...any) {
	l.log.Write(context.Background(), STAT, relatedId, fmt.Sprintf(format, a...))
}

func (l *logger) StatCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(ctx, STAT, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) StatfCtx(ctx context.Context, relatedId, format string, a ...any) {
	l.log.Write(ctx, STAT, relatedId, fmt.Sprintf(format, a...))
}

// ----------- fatal log ---------------

func (l *logger) Fatal(relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(context.Background(), FATAL, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) Fatalf(relatedId, format string, a ...any) {
	l.log.Write(context.Background(), FATAL, relatedId, fmt.Sprintf(format, a...))
}

func (l *logger) FatalCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(ctx, FATAL, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) FatalfCtx(ctx context.Context, relatedId, format string, a ...any) {
	l.log.Write(ctx, FATAL, relatedId, fmt.Sprintf(format, a...))
}

// ----------- severe log ---------------

func (l *logger) Severe(relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(context.Background(), SEVERE, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) Severef(relatedId, format string, a ...any) {
	l.log.Write(context.Background(), SEVERE, relatedId, fmt.Sprintf(format, a...))
}

func (l *logger) SevereCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(ctx, SEVERE, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) SeverefCtx(ctx context.Context, relatedId, format string, a ...any) {
	l.log.Write(ctx, SEVERE, relatedId, fmt.Sprintf(format, a...))
}

// ----------- alert log ---------------

// 记录Debug日志：在生产环境下不输出信息
func (l *logger) Alert(relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(context.Background(), ALERT, relatedId, MsgMarshal(msg), fields...)
}

// 记录Debug日志： 在生产环境下不输出信息
func (l *logger) Alertf(relatedId, format string, a ...any) {
	l.log.Write(context.Background(), ALERT, relatedId, fmt.Sprintf(format, a...))
}

func (l *logger) AlertCtx(ctx context.Context, relatedId string, msg interface{}, fields ...Field) {
	l.log.Write(ctx, ALERT, relatedId, MsgMarshal(msg), fields...)
}

func (l *logger) AlertfCtx(ctx context.Context, relatedId, format string, a ...any) {
	l.log.Write(ctx, ALERT, relatedId, fmt.Sprintf(format, a...))
}
